﻿/*
 * Comments.
 * ---------------------------------------------------------------------------------------------------
 * Date         |  Who          |  Version      | Description of Change
 * ---------------------------------------------------------------------------------------------------
 * 28/02/12      Gareth B           Alpha 0.0.2   Added Thumbail Support. 
 * 25/04/12      Gareth B           Alpha 0.0.3   Added tableLink to EditImageFor 
 */


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Metadata.Edm;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.IO;
using System.Drawing;
using System.Data.Entity;
using System.Data.EntityClient;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Web.Helpers;
using System.Web.Mvc.Html;
using Bradaz.OpenSource.CustomValidation;


namespace Bradaz.OpenSource.MVC
{
    

    #region Debug Class
    /// <summary>
    /// Extension method to allow us to Debug various Web related areas.
    /// </summary>
    public static class Debug
    {
        #region ModelStateErrors
#if DEBUG
        /// <summary>
        /// Output the properties which are causing the issues when 
        /// the model is binding.
        /// </summary>
        public static void ModelStateErrors(ModelStateDictionary modelState)
        {
            var errors = modelState.Where(a => a.Value.Errors.Count > 0)
                .Select(b => new { b.Key, b.Value.Errors })
                .ToArray();

            foreach (var modelStateErrors in errors)
            {
                int count = modelStateErrors.Errors.Count();
                System.Diagnostics.Debug.WriteLine("...Errored When Binding.", modelStateErrors.Key.ToString());

            }

        }
#endif
        #endregion

    }
    #endregion

    #region Extension Methods
    public static class Extensions
    {
        #region ModelStateErrors
        #if DEBUG
        /// <summary>
        /// Output the properties which are causing the issues when 
        /// the model is binding.
        /// </summary>
        public static void ModelStateErrors(this ModelStateDictionary modelState)
        {
            var errors = modelState.Where(a => a.Value.Errors.Count > 0)
                .Select(b => new { b.Key, b.Value.Errors })
                .ToArray();

            foreach (var modelStateErrors in errors)
            {
                int count = modelStateErrors.Errors.Count();
                System.Diagnostics.Debug.WriteLine("...Errored When Binding.", modelStateErrors.Key.ToString());

            }

        }
        #endif
        #endregion


        #region CountAll
        public static int CountAll<TEntity>(this ObjectSet<TEntity> objectSet) where TEntity : class
        {
            int count = 0;
            foreach (var ObjectSet in objectSet)
            {
                if (objectSet != null)
                {
                    count++;
                }
            }

            return count;
        }
        #endregion





    }
    #endregion


}

namespace Bradaz.OpenSource.MVC.HTMLHelpers
{
    #region ImageHelpers Class
    public static class ImageHelpers
    {
        #region UploadImageFor
        /// <summary>
        /// HTML Helper to allow you to upload Images and Preview it.
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="helper"></param>
        /// <param name="expression"></param>
        /// <param name="id"></param>
        /// <param name="name"></param>
        /// <param name="cssclass"></param>
        /// <param name="alt"></param>
        /// <param name="imgId"></param>
        /// <param name="height"></param>
        /// <param name="width"></param>
        /// <returns>HTML String</returns>
        public static MvcHtmlString UploadImageFor<TModel, TProperty>(this HtmlHelper<TModel> helper,
            Expression<Func<TModel, TProperty>> expression, string id = null, string name = null,
            string cssclass = null, string alt = null, string imgId = null, string height = null, string width = null,
            bool thumbnail = false, string thumbAlt = null, string thumbimgId = null, string thumbHeight = null, string thumbWidth = null,
            string thumbName = null)
        {
            const string type = "file";

            if (thumbAlt == null)
            {
                thumbAlt = "thumbAlt";
            }

            if (thumbimgId == null)
            {
                thumbimgId = "thumbnail";
 
            }

            if (thumbHeight == null)
            {
                thumbHeight = "100px";

            }

            if (thumbWidth == null)
            {
                thumbWidth = "100px";
            }

            if (thumbName == null)
            {
                thumbName = "thumbnailImageLoad";
            }

            if (cssclass == null)
            {
                cssclass = "upload";
            }

            if (id == null)
            {
                id = "File1";
            }

            if (name == null)
            {
                name = "imageLoad2";
            }

            if (alt == null)
            {
                alt = "Preview";
            }

            if (imgId == null)
            {
                imgId = "imgThumbnail2";
            }

            if (height == null)
            {
                height = "126px";
            }

            if (width == null)
            {
                width = "126px";
            }


            ///Firstly we build the input tag.
            //--Add the CSS class.
            var fileBuilder = new TagBuilder("input");
            fileBuilder.AddCssClass(cssclass);
            //--Add the name.
            fileBuilder.MergeAttribute("name", name);
            //--Add the id.
            fileBuilder.MergeAttribute("id", id);
            //--Add the type.
            fileBuilder.MergeAttribute("type", type);

            ///Secondly we build the img tag.
            //--Add the alt.
            var imgBuilder = new TagBuilder("img");
            imgBuilder.MergeAttribute("alt", alt);
            //--Add the id.
            imgBuilder.MergeAttribute("id", imgId);
            //--Add the height and width.
            imgBuilder.MergeAttribute("height", height);
            imgBuilder.MergeAttribute("width", width);

            var thumbnailBuilder = new TagBuilder("img");
            if (thumbnail == true)
            {
                ///Thirdly we build the thumbnail img tag.
                //--Add the name.
                thumbnailBuilder.MergeAttribute("name", name);
                //--Add the alt.
                thumbnailBuilder.MergeAttribute("alt", thumbAlt);
                //--Add the id.
                thumbnailBuilder.MergeAttribute("id", thumbimgId);
                //--Add the height and width.
                thumbnailBuilder.MergeAttribute("height", thumbHeight);
                thumbnailBuilder.MergeAttribute("width", thumbWidth);
            }

            ///Merge the two together into a p tag.
            var mergedBuilder = new TagBuilder("div");
            mergedBuilder.AddCssClass("file-upload");
            mergedBuilder.InnerHtml += fileBuilder.ToString(TagRenderMode.SelfClosing);
            mergedBuilder.InnerHtml += imgBuilder.ToString(TagRenderMode.SelfClosing);

            if(thumbnail == true)
            {
                mergedBuilder.InnerHtml += thumbnailBuilder.ToString(TagRenderMode.SelfClosing);
            }

            return MvcHtmlString.Create(mergedBuilder.ToString());

        }
        #endregion

        #region  DisplayImageFor
        public static MvcHtmlString DisplayImageFor<TModel, TProperty>(this HtmlHelper<TModel> helper,
            Expression<Func<TModel, TProperty>> expression, string alt = null, string action = null, string controller = null,
            string actionParameterName = null, string height = null, string width = null, bool thumbnail = false, bool tableLink = false)
        {

            if (String.IsNullOrEmpty(alt))
            {
                string _name = ExpressionHelper.GetExpressionText(expression);
                alt = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(_name);
            }

            if (String.IsNullOrEmpty(height))
            {
                if (thumbnail == true)
                {
                    height = "100px";
                }
                else
                {
                    height = "126px";
                }
            }

            if (String.IsNullOrEmpty(width))
            {
                if (thumbnail == true)
                {
                    width = "100px";
                }
                else
                {
                    width = "126px";
                }
            }

            if (String.IsNullOrEmpty(actionParameterName))
            {
                actionParameterName = "id";
            }

            ///---Set the default src settings if null
            ///--- src element is made up of action, controller and acionParameterName

            if (String.IsNullOrEmpty(action))
            {
                if (thumbnail == false)
                {
                    action = "GetImage";
                }
                else
                {
                    action = "GetThumbnailImage";
                }

            }

            if (String.IsNullOrEmpty(controller))
            {
                controller = "Image";
            }

            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
            Object value = metadata.Model;
            Type valueType = metadata.Model.GetType();
            //String name1 = metadata.PropertyName;

            /*
            string name = ExpressionHelper.GetExpressionText(expression);
            string fullName = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
             */
            string src = null;

            if (ObjectValidation.IsStringType(valueType))
            {
                if (tableLink == true)
                {
                    value += "?tableLink=true";
                }

                src = String.Format(CultureInfo.InvariantCulture,
                "/{0}/{1}/{2}", controller, action, value);
            }

            var imgBuilder = new TagBuilder("img");

            imgBuilder.MergeAttribute("alt", alt);
            imgBuilder.MergeAttribute("src", src);
            imgBuilder.MergeAttribute("height", height);
            imgBuilder.MergeAttribute("width", width);


            return MvcHtmlString.Create(imgBuilder.ToString(TagRenderMode.SelfClosing));


        }
        #endregion

        #region EditImageFor
        public static MvcHtmlString EditImageFor<TModel, TProperty>(this HtmlHelper<TModel> helper,
            Expression<Func<TModel, TProperty>> expression, string id = null, string name = null,
            string cssclass = null, string alt = null, string imgId = null, string height = null, string width = null,
            string action = null, string controller = null,bool tableLink = false)
        {
            const string type = "file";

            if (String.IsNullOrEmpty(cssclass))
            {
                cssclass = "upload";
            }

            if (String.IsNullOrEmpty(id))
            {
                id = "File1";
            }

            if (String.IsNullOrEmpty(name))
            {
                name = "imageLoad2";
            }

            if (String.IsNullOrEmpty(alt))
            {
                alt = "Preview";
            }

            if (String.IsNullOrEmpty(imgId))
            {
                imgId = "imgThumbnail2";
            }

            if (String.IsNullOrEmpty(height))
            {
                height = "126px";
            }

            if (String.IsNullOrEmpty(width))
            {
                width = "126px";
            }

            if (String.IsNullOrEmpty(action))
            {
                action = "GetImage";

            }

            if (String.IsNullOrEmpty(controller))
            {
                controller = "Image";
            }

            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
            Object value = metadata.Model;
            Type valueType = metadata.Model.GetType();
            string src = null;

            if (ObjectValidation.IsStringType(valueType))
            {
                if (tableLink == true)
                {
                    value += "?tableLink=true";
                }

                src = String.Format(CultureInfo.InvariantCulture,
                "/{0}/{1}/{2}", controller, action, value);
            }


            ///Firstly we build the input tag.
            //--Add the CSS class.
            var fileBuilder = new TagBuilder("input");
            fileBuilder.AddCssClass(cssclass);
            //--Add the name.
            fileBuilder.MergeAttribute("name", name);
            //--Add the id.
            fileBuilder.MergeAttribute("id", id);
            //--Add the type.
            fileBuilder.MergeAttribute("type", type);

            ///Secondly we build the img tag.
            //--Add the alt.
            var imgBuilder = new TagBuilder("img");
            imgBuilder.MergeAttribute("alt", alt);
            //--Add the id.
            imgBuilder.MergeAttribute("id", imgId);
            //--Add the height and width.
            imgBuilder.MergeAttribute("height", height);
            imgBuilder.MergeAttribute("width", width);
            //--Add src element.
            imgBuilder.MergeAttribute("src", src);

            ///Merge the two together into a p tag.
            var mergedBuilder = new TagBuilder("div");
            mergedBuilder.AddCssClass("file-upload");
            mergedBuilder.InnerHtml += fileBuilder.ToString(TagRenderMode.SelfClosing);
            mergedBuilder.InnerHtml += imgBuilder.ToString(TagRenderMode.SelfClosing);

            return MvcHtmlString.Create(mergedBuilder.ToString());

        }
        #endregion

    }
    #endregion
}

